package com.imcrl.performance
{
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	import flash.utils.describeType;
	import flash.utils.setTimeout;
	
	
	/**
	 * 
	 * @author crl
	 * 
	 */	
	public class PerformanceTest
	{
		
		/**
		 * 
		 * @param o
		 * @param loop
		 * @return 
		 * 
		 */		
		public static function suitFromObject(o:ISuitTest):Vector.<MethodTest> {
			var methodList:Vector.<MethodTest>;
			
			var desc:XML = describeType(o);
			var type:String = desc.@name;
			
			
			var methods:XMLList = desc..method.(@declaredBy == type);
			var l:uint = methods.length();
			var methodTest:MethodTest;
			
			var list:Array=[];
			var loop:int=o.loop;
			for (var i:int=0; i<l; i++) {
				var method:XML = methods[i];
				var name:String = method.@name;
				if(name.indexOf("test_") ==-1)continue;
				methodTest=new MethodTest(o[name]);
				methodTest.name=type+"."+name;
				methodTest.loops=loop;
				list.push(methodTest);
			}
			list.sortOn("name",Array.CASEINSENSITIVE);
			
			methodList=new Vector.<MethodTest>(list.length,true);
			i=0;
			for each(methodTest in list){
				methodList[i++]=methodTest;
			}
			
			return methodList;
		}
		
		
		private var queue:Vector.<MethodTest>;
		private var timer:Timer;
		
		private var position:int=0;
		
		private var loop:int=1;
		public function PerformanceTest(loop:int=1)
		{
			this.loop=loop;
			queue =new Vector.<MethodTest>();
			timer = new Timer(50,1);
			timer.addEventListener(TimerEvent.TIMER,handleTimer);
		}
		
		/**
		 * 添加单个方法代理测试; 
		 * @param method
		 * 
		 */		
		public function add(method:MethodTest):void{
			queue.push(method);
		}
		
		/**
		 * 添加列表; 
		 * @param methods
		 * 
		 */		
		public function addSuit(suit:ISuitTest):void{
			var methods:Vector.<MethodTest>=suitFromObject(suit);
			for each(var method:MethodTest in methods){
				queue.push(method);
			}
		}
		
		private function handleTimer(event:Event):void{
			next();
		}
		
		public function next():void{
			if (queue.length == 0){
				trace("\n测试结束");
				return;
			}
			
			if(position==queue.length){
				position=0;
				loop--;
				
				if(loop==0){
					trace("\n测试结束");
					return;
				}else{
					trace("");
				}
			}
			
			queue[position].run();
			
			position++;
			
			if( queue.length > 0 ) {
				timer.reset();
				timer.start();
			}
		}
		
		public function laterStart():void{
			setTimeout(next,2000);
		}
	}
}